﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.Runtime.Session;
using Abp.UI;
using SingleUserMall.Authorization.Users;
using SingleUserMall.Common;
using SingleUserMall.Items.Form;
using SingleUserMall.Items.VO;
using SingleUserMall.Mall.VO;
using SingleUserMall.Orders;
using SingleUserMall.Orders.VO;
using SingleUserMall.ShoppingCarts;
using SingleUserMall.Stores;
using SingleUserMall.Users.VO;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static SingleUserMall.Items.Item;

namespace SingleUserMall.Items
{
    public class ItemAppService : SingleUserMallAppServiceBase, IItemAppService
    {
        private readonly IRepository<Item, long> _itemRepository;
        private readonly IRepository<ItemComment, long> _itemCommentRepository;
        private readonly IRepository<ItemSpec, long> _itemSpecRepository;
        private readonly IRepository<ItemCategory, long> _itemCategoryRepository;
        private readonly IRepository<GroupOrder, long> _groupOrderRepository;
        private readonly IRepository<UserFavorite, long> _userFavoriteRepository;
        private readonly IRepository<BusinessScope, long> _businessScopeRepository;
        private readonly IRepository<Store, int> _storeRepository;
        private readonly IRepository<ItemBargain, long> _itemBargainRepository;
        private readonly IRepository<Order, long> _orderRepository;
        private readonly IRepository<User, long> _userRepository;
        private readonly IRepository<BargainRecord, long> _bargainRecordRepository;

        public ItemAppService(
            IRepository<Item, long> itemRepository,
            IRepository<ItemComment, long> itemCommentRepository,
            IRepository<ItemSpec, long> itemSpecRepository,
            IRepository<ItemCategory, long> itemCategoryRepository,
            IRepository<GroupOrder, long> groupOrderRepository,
            IRepository<UserFavorite, long> userFavoriteRepository,
            IRepository<BusinessScope, long> businessScopeRepository,
            IRepository<Store, int> storeRepository,
            IRepository<ItemBargain, long> itemBargainRepository,
            IRepository<Order, long> orderRepository,
            IRepository<User, long> userRepository,
            IRepository<BargainRecord, long> bargainRecordRepository
            )
        {
            _itemRepository = itemRepository;
            _itemCommentRepository = itemCommentRepository;
            _itemSpecRepository = itemSpecRepository;
            _itemCategoryRepository = itemCategoryRepository;
            _groupOrderRepository = groupOrderRepository;
            _userFavoriteRepository = userFavoriteRepository;
            _businessScopeRepository = businessScopeRepository;
            _storeRepository = storeRepository;
            _itemBargainRepository = itemBargainRepository;
            _orderRepository = orderRepository;
            _userRepository = userRepository;
            _bargainRecordRepository = bargainRecordRepository;
        }
        [AbpAuthorize]
        public async Task FavoriteAsync(SingleId<long> form)
        {
            var userId = AbpSession.GetUserId();
            var count = await _userFavoriteRepository.CountAsync(x => x.UserId == userId && x.ItemId == form.Id);
            if (count == 0)
            {
                await _userFavoriteRepository.InsertAsync(new UserFavorite
                {
                    UserId = userId,
                    ItemId = form.Id
                });
            }
            else
            {
                throw new UserFriendlyException("您已收藏");
            }
        }
        public async Task<ItemAppVO> GetItemAsync(ItemOneForm form)
        {
            var userId = AbpSession.UserId ?? 0;
            var item = await _itemRepository.FirstOrDefaultAsync(form.Id);
            var store = await _storeRepository.FirstOrDefaultAsync(item.StoreId);
            var isStartBargin = _itemBargainRepository.Count(x => (x.UserId == userId) && x.ItemId == form.Id && !x.IsOver && !x.IsDown) > 0;
            var commentQuery = _itemCommentRepository.GetAll().Where(x => x.ItemId == form.Id);
            var grouporderQuery = _groupOrderRepository.GetAll().Where(x => x.ItemId == form.Id && x.Status == GroupOrderStatus.Grouping);
            var bargainsQuery = _itemBargainRepository.GetAll().Where(x => x.ItemId == form.Id && !x.IsOver).WhereIf(form.BargainUserId.HasValue, x => x.UserId == form.BargainUserId)
            .OrderByDescending(x => x.UserId == userId).ThenByDescending(x => x.UserList.Contains(userId.ToString())).ThenByDescending(x => x.CreationTime);
            var bargain = await _itemBargainRepository.FirstOrDefaultAsync(x => x.ItemId == form.Id && !x.IsOver && form.BargainUserId.HasValue && x.UserId == form.BargainUserId);
            return item.ToVO<Item, ItemAppVO>((i, vo) =>
            {
                vo.IsStartBargin = isStartBargin;
                vo.ItemSpecs = i.ItemSpecs.ToListVO<ItemSpec, ItemSpecVO>((k, svo) =>
                {
                    svo.StoreId = k.Item.StoreId;
                });
                vo.ItemSkuCategories = i.ItemSkuCategories.ToListVO<ItemSkuCategory, ItemSkuCategoryVO>((isc, iscvo) =>
                {
                    iscvo.ItemSkus = isc.ItemSkus.ToListVO<ItemSku, ItemSkuVO>();
                });
                vo.GroupOrders = grouporderQuery.OrderByDescending(x => x.CreationTime).Take(5).ToList().ToListVO<GroupOrder, GroupOrderMiniVO>((go, govo) =>
                {
                    govo.inUser = go.User;
                });
                vo.BarginItems = bargainsQuery.Take(20).ToList().ToListVO<ItemBargain, BargainVO>((ib, ibvo) =>
                {
                    ibvo.inUser = ib.User;
                    ibvo.IsStart = ib.User.Id == userId;
                    string[] userlist = ib.UserList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    ibvo.BargainUsers = UserManager.FindUsersByIds(userlist).ToListVO<User, UserMiniVO>((v,uvo)=>
                    {
                        var bargainRecord = _bargainRecordRepository.FirstOrDefault(x => x.UserId == v.Id && x.ItemBargainId== ib.Id);
                        if(bargainRecord != null)
                        {
                            uvo.UserReducedPrice = bargainRecord.UserReducedPrice;
                            uvo.ReduceTime = bargainRecord.CreationTime;
                        }
                        else
                        {
                            uvo.UserReducedPrice = ib.ReducedPrice / ib.ActualBargainTimes;
                        }        
                    });
                });
                vo.IsFavorite = _userFavoriteRepository.Count(x => x.UserId == userId && x.ItemId == item.Id) > 0;
                vo.Star = ItemManager.GetItemStar(i.Id);
                vo.DividendAmountView = ((int)(i.DividendAmount * 100)).ToString();
                if(i.Timelimit > 0)
                {
                    vo.DividendAmountViewByYear = ((int)(i.DividendAmount * 100 / i.Timelimit * 12)).ToString();
                }
                if (bargain != null)
                {
                    vo.ReducedPrice = bargain.ReducedPrice;
                    vo.BargainStartTime = bargain.CreationTime;
                    vo.BargainEndTime = bargain.CreationTime.AddDays(+1);
                }
                var order = _orderRepository.FirstOrDefault(x => x.UserId == userId && x.ItemId == i.Id && x.ShoppingCartType == ShoppingCartType.TreeShopping && x.Status == OrderStatus.Paid);
                vo.DividendItemStatus = order != null ? order.DividendItemStatus : DividendStatus.Start;
            });
        }

        public async Task<ListResultDto<ItemCategoryVO>> GetItemCategoriesAsync(ItemCategorySearchForm form)
        {
            var categories = _itemCategoryRepository.GetAll().Where(x => x.Enabled)
                .WhereIf(form.StoreId.HasValue, x => x.StoreId == form.StoreId)
                .WhereIf(form.ItemCategoryId.HasValue, x => x.ParentId == form.ItemCategoryId)
                .WhereIf(!form.ItemCategoryId.HasValue, x => x.ParentId == null)
                .OrderBy(x => x.Sort).ThenByDescending(x => x.CreationTime);
            return await categories.ToListResultDtoAsync<ItemCategory, ItemCategoryVO>((i, vo) =>
            {
                vo.SubItemCategories = _itemCategoryRepository.GetAll()
                .Where(x => x.ParentId == i.Id).ToList().ToListVO<ItemCategory, SubItemCategoryVO>();
            });
        }
        public async Task<ListResultDto<ItemCategoryVO>> GetIndexItemCategorysAsync()
        {
            var category = _itemCategoryRepository.GetAll().Where(x => x.Enabled).OrderBy(x => x.Sort).ThenByDescending(x => x.CreationTime).Take(9);
            return await category.ToListResultDtoAsync<ItemCategory, ItemCategoryVO>((i, vo) =>
            {
                vo.SubItemCategories = _itemCategoryRepository.GetAll()
                .Where(x => x.ParentId == i.Id).ToList().ToListVO<ItemCategory, SubItemCategoryVO>();
            });
        }

        public async Task<PagedResultDto<ItemCommentVO>> GetItemCommentsAsync(CommentSearchForm form)
        {
            var query = _itemCommentRepository.GetAll().Where(x => x.ItemId == form.ItemId)
                .WhereIf(!string.IsNullOrWhiteSpace(form.Tag) && form.Tag != "全部", x => x.Tags.Contains(form.Tag))
                .WhereIf(form.HasComment, x => x.Comment != null && x.Comment != "")
                .OrderByDescending(x => x.CreationTime);
            return await query.ToPagedResultDtoAsync<ItemComment, ItemCommentVO>(form, (c, vo) =>
            {
                vo.inUser = c.User;
            });
        }

        public async Task<ItemCommentTotalVO> GetItemCommentTotalAsync(ItemCommentTotalForm form)
        {
            var commentQuery = _itemCommentRepository.GetAll().Where(x => x.ItemId == form.ItemId);
            var array = new Dictionary<string, string>();
            form.Tags.ForEach(tag =>
            {
                var count = commentQuery.WhereIf(!string.IsNullOrEmpty(tag) && tag != "全部", x => x.Tags.Contains(tag)).Count();
                array.Add(tag, count.ToString());
            });
            return await Task.FromResult(new ItemCommentTotalVO
            {
                TagValues = array
            });
        }


        public async Task<PagedResultDto<ItemMiniVO>> GetLimitItemsAsync(LimitItemSearch form)
        {
            var limitTime = DateTime.Now;
            var tomorrowLimitTime = limitTime.Date.AddDays(1).Date;
            var afterTomorrow = limitTime.Date.AddDays(2).Date;
            var query = _itemRepository.GetAll().Where(x => x.IsSale && x.IsTimeLimit)
                .WhereIf(form.StoreId.HasValue, x => x.StoreId == form.StoreId);
            if (form.Option == LimitOption.TodayStart)
            {
                query = query.Where(x => x.LimitBeginTime < limitTime && x.LimitEndTime > limitTime).OrderByDescending(x => x.TotalSale);
            }
            else if (form.Option == LimitOption.TodayNoStart)
            {
                query = query.Where(x => x.LimitBeginTime > limitTime && x.LimitBeginTime < tomorrowLimitTime && x.LimitEndTime > limitTime).OrderByDescending(x => x.TotalSale);
            }
            else if (form.Option == LimitOption.TomorrowStart)
            {
                query = query.Where(x => x.LimitBeginTime > tomorrowLimitTime && x.LimitBeginTime < afterTomorrow).OrderByDescending(x => x.TotalSale);
            }
            return await query.ToPagedResultDtoAsync<Item, ItemMiniVO>(form, (i, vo) =>
            {
                vo.Star = ItemManager.GetItemStar(i.Id);
            });
        }
        public async Task<PagedResultDto<ItemMiniVO>> GetItemsByTreeAsync(CategoryItemSearchForm form)
        {
            var query = _itemRepository.GetAll().Where(x => x.IsSale && x.ItemType == ItemsType.ShoppingItems && x.TreeCount > 0&&x.StoreId==form.StoreId).OrderBy(a=>a.Price);
            return await query.ToPagedResultDtoAsync<Item, ItemMiniVO>(form,(i,vo)=> { });
        }
        public async Task<PagedResultDto<ItemMiniVO>> GetItemsAsync(CategoryItemSearchForm form)
        {
            try
            {
                var itemCategoryIds = new List<long>();
                if (form.ItemCategoryId.HasValue)
                {
                    itemCategoryIds.Add(form.ItemCategoryId.Value);
                    var itemCategories = await _itemCategoryRepository.GetAllListAsync(x => x.ParentId == form.ItemCategoryId);
                    itemCategories.ForEach(x =>
                    {
                        itemCategoryIds.Add(x.Id);
                    });
                }
                var newTime = DateTime.Now.AddDays(-SingleUserMallConsts.NewDays);
                var query = _itemRepository.GetAll().Where(x => x.IsSale && x.ItemType == ItemsType.ShoppingItems && x.TreeCount == 0)
                    .WhereIf(form.StoreId.HasValue && form.StoreId != 1, x => x.StoreId == form.StoreId)
                    .WhereIf(itemCategoryIds.Count > 0, x => itemCategoryIds.Contains(x.ItemCategoryId))
                    .WhereIf(form.RecommendCategoryId.HasValue, x => x.RecommendCategoryId == form.RecommendCategoryId)
                    .WhereIf(!string.IsNullOrEmpty(form.Keywords),
                        x => x.Name.Contains(form.Keywords) || x.Tags.Contains(form.Keywords))
                    .WhereIf(form.IsWholesale.HasValue, x => x.IsWholesale == form.IsWholesale)
                    .WhereIf(form.IsGroup.HasValue, x => x.IsGroup == form.IsGroup)
                    .WhereIf(form.IsTimeLimit.HasValue, x => x.IsTimeLimit == form.IsTimeLimit)
                    .WhereIf(form.IsHot.HasValue, x => x.IsHot == form.IsHot)
                    .WhereIf(form.IsBargain.HasValue, x => x.IsBargain == form.IsBargain)
                    .WhereIf(form.MinPrice.HasValue, x => x.Price >= form.MinPrice.Value)
                    .WhereIf(form.MaxPrice.HasValue, x => x.Price <= form.MaxPrice.Value)
                    .WhereIf(form.IsNew, x => x.CreationTime > newTime);
                if (form.Option == ItemOption.Normal)
                {
                    query = query.OrderByDescending(x => x.IsPop).ThenByDescending(x => x.IsHot).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
                }
                else if (form.Option == ItemOption.Price)
                {
                    query = query.OrderBy(x => x.Price).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
                }
                else if (form.Option == ItemOption.PriceDesc)
                {
                    query = query.OrderByDescending(x => x.Price).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
                }
                else if (form.Option == ItemOption.SaleDesc)
                {
                    query = query.OrderByDescending(x => x.MonthSale).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
                }
                else
                {
                    query = query.OrderByDescending(x => x.IsPop).ThenByDescending(x => x.IsHot).ThenByDescending(x => x.CreationTime).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.MonthSale);
                }
                var userZeroBuyQty = _orderRepository.GetAll().Count(x => x.OrderDetails.FirstOrDefault().ItemSpec.Item.IsBargain == true && x.Status == OrderStatus.Paid);
                return await query.ToPagedResultDtoAsync<Item, ItemMiniVO>(form, (i, vo) =>
                {
                    vo.Star = ItemManager.GetItemStar(i.Id);
                    vo.UserZeroBuyQty = userZeroBuyQty;
                });
            }
            catch (Exception ex)
            {
                Writelog("程序发生错误："+ex.Message);
                throw new UserFriendlyException(ex.Message);
            }
        }
        
        public static void Writelog(string msg)
        {
            StreamWriter stream;
            //写入日志内容
            string path = AppDomain.CurrentDomain.BaseDirectory;
            //检查上传的物理路径是否存在，不存在则创建
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            stream = new StreamWriter(path + "\\log.txt", true, Encoding.Default);
            stream.Write(DateTime.Now.ToString() + ":" + msg);
            stream.Write("\r\n");
            stream.Flush();
            stream.Close();
        }
        public async Task<PagedResultDto<ItemMiniVO>> GetDividendItemsAsync(CategoryItemSearchForm form)
        {
            var userId = AbpSession.UserId;
            var itemCategoryIds = new List<long>();
            if (form.ItemCategoryId.HasValue)
            {
                itemCategoryIds.Add(form.ItemCategoryId.Value);
                var itemCategories = await _itemCategoryRepository.GetAllListAsync(x => x.ParentId == form.ItemCategoryId);
                itemCategories.ForEach(x =>
                {
                    itemCategoryIds.Add(x.Id);
                });
            }
            var newTime = DateTime.Now.AddDays(-SingleUserMallConsts.NewDays);
            var query = _itemRepository.GetAll().Where(x => x.IsSale && x.ItemType == ItemsType.DividendItems)
                .WhereIf(form.StoreId.HasValue && form.StoreId != 1, x => x.StoreId == form.StoreId)
                .WhereIf(itemCategoryIds.Count > 0, x => itemCategoryIds.Contains(x.ItemCategoryId))
                .WhereIf(form.RecommendCategoryId.HasValue, x => x.RecommendCategoryId == form.RecommendCategoryId)
                .WhereIf(!string.IsNullOrEmpty(form.Keywords),
                    x => x.Name.Contains(form.Keywords) || x.Tags.Contains(form.Keywords))
                .WhereIf(form.IsBargain.HasValue, x => x.IsBargain == form.IsBargain)
                .WhereIf(form.MinPrice.HasValue, x => x.Price >= form.MinPrice.Value)
                .WhereIf(form.MaxPrice.HasValue, x => x.Price <= form.MaxPrice.Value)
                .WhereIf(form.IsNew, x => x.CreationTime > newTime);
            if (form.Option == ItemOption.Normal)
            {
                query = query.OrderByDescending(x => x.IsPop).ThenByDescending(x => x.IsHot).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
            }
            else if (form.Option == ItemOption.Price)
            {
                query = query.OrderBy(x => x.Price).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
            }
            else if (form.Option == ItemOption.PriceDesc)
            {
                query = query.OrderByDescending(x => x.Price).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
            }
            else if (form.Option == ItemOption.SaleDesc)
            {
                query = query.OrderByDescending(x => x.MonthSale).ThenBy(x => x.LimitBeginTime).ThenByDescending(x => x.CreationTime);
            }
            else
            {
                query = query.OrderByDescending(x => x.IsPop);
            }
            return await query.ToPagedResultDtoAsync<Item, ItemMiniVO>(form, (i, vo) =>
            {
                vo.Star = ItemManager.GetItemStar(i.Id);
                vo.DividendAmountView = ((int)(i.DividendAmount * 100)).ToString();
                if(i.Timelimit > 0)
                {
                    vo.DividendAmountViewByYear = ((int)(i.DividendAmount * 100 / i.Timelimit * 12)).ToString();
                }
                var order = _orderRepository.FirstOrDefault(x => x.UserId == userId.Value && x.ItemId == i.Id && x.ShoppingCartType == ShoppingCartType.TreeShopping && x.Status == OrderStatus.Paid);
                vo.DividendItemStatus = order != null ? order.DividendItemStatus : DividendStatus.Start;
            });
        }

        [AbpAuthorize]
        public async Task NotFavoriteAsync(SingleId<long> form)
        {
            var userId = AbpSession.GetUserId();
            await _userFavoriteRepository.DeleteAsync(x => x.UserId == userId && x.ItemId == form.Id);
        }

        public async Task<ListResultDto<BusinessScopeVO>> GetEnableBusinessScopeAsync(BusinesssSearchForm form)
        {
            var query = _businessScopeRepository.GetAll()
                .Where(x => x.IsUse)
                .WhereIf(!string.IsNullOrEmpty(form.Keywords), x => x.Name.Contains(form.Keywords))
                .OrderByDescending(x => x.CreationTime);
            return await query.ToListResultDtoAsync<BusinessScope, BusinessScopeVO>((v, vo) => { });
        }

        public async Task<ListResultDto<ItemMiniVO>> GetRecommendItemsByIdAsync(SingleId<long> form)
        {
            var item = _itemRepository.FirstOrDefault(form.Id);
            var categoryParentId = item.ItemCategory.ParentId;
            var query = _itemRepository.GetAll().Where(x => x.IsSale && x.Id != item.Id)
                .Where(x => x.ItemCategory.ParentId == categoryParentId).OrderBy(x => x.Sort)
                .ThenByDescending(x => x.TotalSale)
                .ThenByDescending(x => x.MonthSale).Take(4);
            return await query.ToListResultDtoAsync<Item, ItemMiniVO>();
        }

        public async Task<ItemAppVO> JoinItemBargain(SingleId<long> form)
        {
            var userId = AbpSession.GetUserId();
            var user = _userRepository.FirstOrDefault(userId);
            if(user == null)
            {
                throw new UserFriendlyException("该用户不存在");
            }
            var bargain = _itemBargainRepository.FirstOrDefault(x => x.Id == form.Id && !x.IsOver);
            if (bargain == null)
            {
                throw new UserFriendlyException("该商品砍价已经结束");
            }
            else
            {
                if (bargain.UserList.Contains(userId.ToString()))
                {
                    throw new UserFriendlyException("您已经砍过一次价 不能再次参与");
                }
                if (bargain.IsDown)
                {
                    throw new UserFriendlyException("该商品已到底价，不能再次砍价");
                }
                if (bargain.Item.IsSaleOut)
                {
                    throw new UserFriendlyException("该商品已售罄 谢谢参与");
                }
                bargain.ActualBargainTimes += 1;
                bargain.UserList = string.IsNullOrEmpty(bargain.UserList) ? string.Format(",{0},", userId) : string.Format("{0}{1},", bargain.UserList, userId);
                decimal reducePrice = 0;
                decimal newPrice = 0;
                if (bargain.ActualBargainTimes < bargain.Item.BargainTimes)
                {
                    var minPrice = (bargain.ActualBargainPrice - bargain.Item.BargainPrice) / (bargain.Item.BargainTimes - bargain.ActualBargainTimes);
                    decimal radomPrice = Convert.ToDecimal((new Random().Next(1,50))*0.01);
                     newPrice = minPrice - radomPrice;
                    if(newPrice < 0)
                    {
                        bargain.ActualBargainPrice = bargain.Item.BargainPrice;
                        bargain.ReducedPrice = bargain.Item.Price - bargain.ActualBargainPrice;
                        bargain.IsDown = true;
                    }
                    else
                    {
                        bargain.ActualBargainPrice -= newPrice;
                        bargain.ReducedPrice = bargain.Item.Price - bargain.ActualBargainPrice;
                    }
                }
                else
                {
                    newPrice = bargain.ActualBargainPrice - bargain.Item.BargainPrice;
                    bargain.ActualBargainPrice = bargain.Item.BargainPrice;
                    bargain.ReducedPrice = bargain.Item.Price - bargain.ActualBargainPrice;
                    bargain.IsDown = true;
                }

                _bargainRecordRepository.Insert(new BargainRecord { UserId = userId, ItemBargainId = bargain.Id, UserReducedPrice = newPrice });
                CurrentUnitOfWork.SaveChanges();
                var item = await _itemRepository.FirstOrDefaultAsync(bargain.Item.Id);
                var store = await _storeRepository.FirstOrDefaultAsync(item.StoreId);
                var commentQuery = _itemCommentRepository.GetAll().Where(x => x.ItemId == item.Id);
                var grouporderQuery = _groupOrderRepository.GetAll().Where(x => x.ItemId == item.Id && x.Status == GroupOrderStatus.Grouping);
                var bargainsQuery = _itemBargainRepository.GetAll().Where(x => x.ItemId == item.Id && !x.IsOver)
                    .OrderByDescending(x => x.UserId == userId).ThenByDescending(x => x.UserList.Contains(userId.ToString())).ThenByDescending(x => x.CreationTime);
                var isBargainComplete = _itemBargainRepository.Count(x => (x.UserId == userId || x.UserList.Contains(userId.ToString())) && x.ItemId == item.Id && !x.IsOver && x.IsDown) > 0;
                return item.ToVO<Item, ItemAppVO>((i, vo) =>
                {
                    vo.IsStartBargin = false;
                    vo.ReducedPrice = bargain.ReducedPrice;
                    vo.ItemSpecs = i.ItemSpecs.ToListVO<ItemSpec, ItemSpecVO>((k, svo) =>
                    {
                        svo.StoreId = k.Item.StoreId;
                    });
                    vo.ItemSkuCategories = i.ItemSkuCategories.ToListVO<ItemSkuCategory, ItemSkuCategoryVO>((isc, iscvo) =>
                    {
                        iscvo.ItemSkus = isc.ItemSkus.ToListVO<ItemSku, ItemSkuVO>();
                    });
                    vo.GroupOrders = grouporderQuery.OrderByDescending(x => x.CreationTime).Take(5).ToList().ToListVO<GroupOrder, GroupOrderMiniVO>((go, govo) =>
                    {
                        govo.inUser = go.User;
                    });
                    vo.BarginItems = bargainsQuery.Take(20).ToList().ToListVO<ItemBargain, BargainVO>((ib, ibvo) =>
                    {
                        ibvo.inUser = ib.User;
                        ibvo.IsStart = ib.User.Id == userId;
                        string[] userlist = ib.UserList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        ibvo.BargainUsers = UserManager.FindUsersByIds(userlist).ToListVO<User, UserMiniVO>();
                    });
                    vo.IsFavorite = _userFavoriteRepository.Count(x => x.UserId == userId && x.ItemId == item.Id) > 0;
                    vo.Star = ItemManager.GetItemStar(i.Id);
                });
            }
        }

        public async Task StartItemBargain(ItemBargainForm form)
        {
            var userId = AbpSession.GetUserId();
            var user = _userRepository.FirstOrDefault(userId);
            if (user == null)
            {
                throw new UserFriendlyException("该用户不存在");
            }
            var itemSpec = _itemSpecRepository.FirstOrDefault(form.SpecId);
            if (itemSpec == null)
            {
                throw new UserFriendlyException("该规格不存在 请重新选择");
            }
            var price = itemSpec.Price;
            var bargain = _itemBargainRepository.FirstOrDefault(x => x.Item.Id == form.ItemId && x.SpecId == form.SpecId && x.UserId == userId && !x.IsOver);
            if (bargain != null)
            {
                throw new UserFriendlyException("您已经发起过该商品特定规格的砍价， 不能重复发起");
            }
            else
            {
                _itemBargainRepository.Insert(new ItemBargain
                {
                    SpecId = form.SpecId,
                    ItemId = form.ItemId,
                    UserId = userId,
                    IsOver = false,
                    ActualBargainPrice = price,
                    ActualBargainTimes = 0,
                    UserList = ""
                });
                await CurrentUnitOfWork.SaveChangesAsync();
            }
        }

        public async Task<PagedResultDto<UserItemBarginVO>> GetItemBarginAsync(ItemBargainSearchForm form)
        {
            var userId = AbpSession.GetUserId();
            var query = _itemBargainRepository.GetAll().Where(x => x.UserId == userId && x.IsOver == form.IsOver).OrderByDescending(x => x.CreationTime);
            var itemBargain = _itemBargainRepository.GetAll().FirstOrDefault(x => x.UserId == userId && x.IsOver == form.IsOver);
            //var item = _itemRepository.GetAll().Where(x => x.Id == itemBargain.ItemId);
            return await query.ToPagedResultDtoAsync<ItemBargain, UserItemBarginVO>(form, (v, vo) =>
            {
                vo.Name = v.Item?.Name;
                vo.Picture = v.ItemSpec?.Picture;
                vo.Price = v.Item?.Price ?? 0;
            });
        }
    }
}
